/* pseudo-codigo.c
	
	Last edit

*/
source file: sthread_user.c


/*
	ESTRUTURAS DE DADOS
*/

/* CLIENTES:
chave: id do client
nao existe repeticao de elemento com a mesma chave;
insercao: ordenada pela chave
procura: no meio do conjunto
remocao: no meio do conjunto

*/
Cliente{
int id;
int numTarefas;
}

list_client_t* create_list_client();
void destroy_list_client(list_client_t*);
void insert_list_client(client_t*);
void remove_list_client(int id);
client_t* get_list_client(list_client_t*,int id);




/* TAREFAS:
chave: vruntime da thread
nao existe repeticao de elemento com a mesma chave;
insercao: ordenacao crescente por vruntime
procura: nao existe
remocao: thread com menor vruntime
	
*/
Thread { 
	sthread_ctx_t *saved_ctx; //contexto....
	sthread_start_func_t start_routine_ptr; //what is this???
	long wake_time;
	int join_tid;
	void* join_ret;
	void* args;
	int tid;          /* meramente informativo */
	client_t *client;
	long vruntime;
	int priority; varia entre 1 e 10
	int nice; varia entre 0 e 10
	int ticks; //incrementado cada vez que é interrompido pelo escalonador
	Estado da Tarefa (bloqueado, executável, execução)
}

queue_thread_t* create_queue_thread();
void destroy_queue_thread(queue_thread_t*);
void insert_queue_thread(queue_thread_t*,thread_t*);
thread_t* remove(queue_thread_t*);

// VARIAVEIS

#define CLOCK_TICK 10000
#define MIN_DELAY 10



//Clientes nesta lista têm pelo menos uma thread activa
Lista ListaDeClientes;
//
tarefa tarefaActiva;

Casos em que ocorre preempção:
É inserido uma thread com vruntime inferior à thread activa
Ocorre quando:
Exit
unlock
post
join


// FUNCOES

// executado sempre que ocorre um tick
Escalonador(função){
int vruntime = (prio+nice)* num_tarefas_deste_cliente
trataOverflow(vruntime);

tarefaActiva.vruntime += (prio+nice)* num_tarefas_deste_cliente

if( existeVrumtimeMaior(tarefaActiva)){

	if( tarefa.vruntime > MIN_DELAY){}
}

void sthread_user_yield(void)
{
\se a tarefa activa for a que tem mais prioridade, nao faz nada e continua em execução
\se não:
	splx(HIGH);
	struct _sthread *old_thr;
	old_thr = active_thr;
	queue_insert(exe_thr_list, old_thr);
	active_thr = queue_remove(exe_thr_list);
	sthread_switch(old_thr->saved_ctx, active_thr->saved_ctx);
	splx(LOW);
}

exit{

depois de processar join_thr_list,
guardar a active_thr na dead_thr_list ou zombie_thr_list,
se for a unica thread do seu client, entao o cliente é removido da client_list
a nova thread activa é a thread da exe_thr_list com menor vruntime

}


